#include <func.h>

typedef struct {
	int id;
	int balance;
	pthread_mutex_t mutex; // 细粒度锁
} Account;

Account acct1 = {1, 100, PTHREAD_MUTEX_INITIALIZER};
// pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 粒度大

void cleanup(void* arg) {
	pthread_mutex_t* mutex = (pthread_mutex_t*)arg;
	pthread_mutex_unlock(mutex);
}

int withdraw(Account* acct, int money) {
	// 上锁
	pthread_mutex_lock(&acct->mutex);
	pthread_cleanup_push(cleanup, &acct->mutex);

	if (acct->balance < money) {
		int n = acct->balance;
		acct->balance = 0;

		pthread_mutex_unlock(&acct->mutex);
		return n;
	}

	sleep(1);	// 放大某些调度的概率

	acct->balance -= money;
	pthread_mutex_unlock(&acct->mutex);
	return money;

	pthread_cleanup_pop(0);
}

void* start_routine(void* arg) {
	int money = (int)arg;
	int n = withdraw(&acct1, money);
	printf("Thread 0x%lx withdraw $%d\n", pthread_self(), n);
	return NULL;
}

int main(int argc, char* argv[])
{
	pthread_t tid1, tid2;
	
	pthread_create(&tid1, NULL, start_routine, (void*)100);
	pthread_create(&tid2, NULL, start_routine, (void*)100);

	pthread_join(tid1, NULL);
	pthread_join(tid2, NULL);
    return 0;
}

